package me.fung.wubi.app.view.build_table

import me.fung.keen.app.view.Presenter
import me.fung.keen.common.DataWrapper
import me.fung.keen.common.TextClipboard
import me.fung.keen.component.message.msg
import me.fung.wubi.app.component.swing.chooseFile
import me.fung.wubi.app.component.swing.saveFileDialog
import me.fung.wubi.app.navigation
import me.fung.wubi.app.view.editor.EDITOR_VIEW
import me.fung.wubi.base.io.localObject
import me.fung.wubi.resource.LocalResource
import me.fung.wubi.worker.builder.BuildConfig
import me.fung.wubi.worker.builder.FileResources
import me.fung.wubi.worker.builder.SimpleTableBuilder
import me.fung.wubi.worker.builder.TableBuilder
import me.fung.wubi.worker.printer.*
import mu.KotlinLogging
import java.io.File

class BuildTablePresenter : Presenter() {
    private val logger = KotlinLogging.logger {}
    val model = DataWrapper(BuildTableModel())

    init {
        localObject.loadFromFile<BuildTableModel>(".default")?.also { model.update { it } }

    }

    fun update(block: BuildTableModel.() -> BuildTableModel) {
        model.update { block() }
    }


    fun loadConfig(fileDir: String) {
        val file = File(fileDir)
        localObject.loadFromFile<BuildTableModel>(file)?.also { model.update { it } }
    }

    fun openSourceFolder() {
        val folder = LocalResource.dir(localObject.path())
        Runtime.getRuntime().exec("explorer.exe $folder");
    }

    fun chooseConfig() {
        chooseFile(localObject.path())?.also { loadConfig(it) }
    }

    fun saveConfig() {
        val filename = saveFileDialog(localObject.path())
        if (filename == null) {
            msg.send { info("取消保存") }
            return
        }
        val file = File(filename)
        localObject.save(file, model.data)
        msg.send { info("已保存到：$filename") }
    }

    fun extractTable() {
        val filename = chooseFile(localObject.path()) ?: return
        navigation.goto(EDITOR_VIEW, listOf(filename))
    }

    private val defaultBuilder: (FileResources) -> TableBuilder<FileResources> = { SimpleTableBuilder() }
    private val defaultPrinter: (File) -> TablePrinter = { SimpleTextPrinter(it) }

    private fun dictOutput(
        buildConfig: BuildConfig = BuildConfig(),
        builderBlock: (FileResources) -> TableBuilder<FileResources> = defaultBuilder,
        printConfig: PrintConfig = PrintConfig(),
        printerBlock: (File) -> TablePrinter = defaultPrinter,
    ) {
        val bf = buildConfig.copy(
            autoShort = model.data.autoShort,
            fullCodeOrShort = model.data.fullCodeOfShort,
            single = model.data.single,
        )
        try {
            val outPutFile = saveFileDialog(localObject.path()) ?: return
            val target = File(outPutFile)
            val builder = builderBlock(model.data.toFileResources())
            val table = builder.build(model.data.toFileResources(), bf)
            val printer = printerBlock(target)
            printer.print(table, printConfig)
            TextClipboard.copy(outPutFile)
            msg.send { info("已生成码表到：$outPutFile") }
        } catch (e: Exception) {
            logger.error { "生成码表异常：" + e.message }
            e.printStackTrace()
            msg.send { error(e) }
        }
    }

    fun simpleOut() {
        dictOutput()
    }

    fun limeOut() {
        dictOutput(
            printerBlock = { LimeTextPrinter(it) }
        )
    }

    fun iBusOut() {
        dictOutput(
            printerBlock = { IBusTextPrinter(it) },
            printConfig = PrintConfig(
                charset = Charsets.UTF_8,
                sign = false
            )
        )

    }
}